<HTML>

<HEAD>
    <META NAME="Author" CONTENT="Borca Daniel">
    <META NAME="Description" CONTENT="a free 32bit DOS extender">
    <META NAME="KeyWords" CONTENT="D3X, DOS extender, 386, 32bit, protected mode, Assembly, DJGPP, WATCOM">

    <TITLE>D3X v0.90.g doc</TITLE>
</HEAD>


<BODY BGCOLOR="#C0C0C0">

    <CENTER>
    <HR SIZE=20 COLOR="#FFFFFF">
    <FONT SIZE=5>D3X<SUP>(tm)</SUP> DOS-Extender v0.90 unleash `g' alpha</FONT>
    <BR>
    <B>
    <FONT SIZE=3>the doc</FONT>
    <BR>*<BR>
    <FONT SIZE=5>Copyright &copy 1998-2001 Borca Daniel</FONT>
    </B>
    <BR>*<BR>
    <FONT SIZE=4><I><A HREF=mailto:dborca@yahoo.com>dborca@yahoo.com</A></I></FONT>
    <BR>
    <FONT SIZE=4><I><A TARGET=_blank HREF=http://www.geocities.com/dborca>http://www.geocities.com/dborca</A></I></FONT>
    <HR SIZE=20 COLOR="#FFFFFF">
    </CENTER>
    <BR><BR>

    <H5 ALIGN=RIGHT>Motto:<BR>
    Combining unlimited control<BR>
    with unmatched efficiency...<BR></H5>
    <BR>

    <OL START=0>
    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="toc">Table of contents</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        <OL START=0>
        <LI><A HREF="#toc">Table of contents</A>
        <LI><A HREF="#description">Description</A>
        <LI><A HREF="#legal">Legal stuff</A>
        <LI><A HREF="#installation">Download & install</A>
        <LI><A HREF="#started">Getting started</A>
        <LI><A HREF="#technical">Tech stuff</A>
        <LI><A HREF="#closing">Closing bytes, words, doublewords...</A>
        </OL>

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="description">Description</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        <FONT COLOR=MAROON><B>D3X</B></FONT> (<B>D</B>OS <B>3</B>2bit e<B>X</B>tender)
        is a <FONT COLOR=MAROON><B>32bit ring 0 protected mode DOS extender</B></FONT>;
        it comes as a stub for 32bit applications: Assembly, DJGPP or WATCOM.<BR>
        The extender is written in 100% assembler, for Assembly freaks...

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="legal">Legal stuff</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        The term <B>D3X</B> is a shorthand and holds no connection with potential owners
        of registered trademarks or other rights.<BR>
        All product names, trademarks and registered trademarks contained in this
        document are the property of their respective holders.<BR>
        The "<B>Software</B>", below, refers to the complete contents of the D3X archive.
        <OL>
        <HR>
        <LI>License agreement:
        <HR>
            Software is provided `as is' and <FONT COLOR=RED><B>without any warranty</B></FONT>; there is no warranty
            of any kind, either expressed or implied, including, but not limited to, the
            implied warranties of merchantability and fitness for a particular purpose.<P>
            Software is freely redistributable as long as this licence is kept with the
            Software. Charging a fee for the Software is prohibited.<P>
            Software, or parts thereof, may be incorporated into other free software
            (that may be obtained free of charge) without requiring permission from the
            author, as long as those parts of the Software that are used remain under this
            licence, as long as due credit is given to the author of the Software in the
            resulting work, and as long as the author is informed of this action.<P>
            Modified forms of the Software may be created and distributed, as long as
            the resulting work remains under this licence, as long as the modified form of
            the Software is distributed with documentation which still gives credit to the
            original author of the Software, as long as the modified form of the Software
            is distributed with a clear statement that it is not the original form of the
            Software as distributed by the author, and as long as the author is informed
            of this action.<P>
            Software, or parts thereof, may be incorporated into other software which
            is not free (for which a fee is charged) as long as permission is granted from
            the author of the Software. The author reserves the right to grant permission
            only for a fee, which may at his option take the form of royalty payments. The
            author also reserves the right to refuse to grant permission if he deems it
            necessary.<P>
            The author of the Software explicitly lay no claim to, and assert no rights
            over, any programs written by other people and extended by the Software (that
            is, executables carrying the extender). Such programs do not fall under this
            licence at all, and may be placed under any licence.<P>
            No other licence applies to the Software, and nothing else grants you any
            permission to copy, modify, sublicence or distribute the Software in any way.
        </OL>

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="installation">Download & install</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        Unzip the archive, preserving the directory structure.
        <OL>
        <HR>
        <LI>Requirements:
        <HR>
            <UL>
            <LI>386 or higher CPU
            <LI>DOS v3.0 or later
            </UL>
        <HR>
        <LI>Rebuilding:
        <HR>
            This baby was <FONT COLOR=MAROON><B>make</B></FONT>'d (from <B>D3X\SRC</B> directory) using:
            <DIR><DIR><TABLE BORDER=0 CELLSPACING=0>
            <TR><TD>NASM v0.98bf</TD><TD><A TARGET=_blank HREF=http://nasm.sourceforge.net>nasm.sourceforge.net</A></TD></TR>
            <TR><TD>ALINK v1.6</TD><TD><A TARGET=_blank HREF=http://alink.home.dhs.org>alink.home.dhs.org</A></TD></TR>
            <TR><TD>DJGPP v2.04</TD><TD><A TARGET=_blank HREF=http://www.delorie.com>www.delorie.com</A> (gcc v3.2, make v3.79.1)</TD></TR>
            <TR><TD>UPX v1.23d (optional) </TD><TD><A TARGET=_blank HREF=http://upx.sourceforge.net>upx.sourceforge.net</A></TD></TR>
            </TABLE></DIR></DIR>
            <BR>Note: using different versions and/or completely different tools might or
            might not yield satisfactory results.
        <HR>
        <LI>Distribution:
        <HR>
<PRE><FONT COLOR="#000060"><B>	<A HREF=d3x-090g.zip>D3X</A>
    |   src.zip			 41060
    +---BIN
    |       stubx.exe		 56840	(112640)
    \---DOC
            d3x.htm			 32227
            d3x.txt			 29423</B></FONT></PRE>
        <HR>
        <LI>History:
        <HR>
            <DIR><DIR><DL>
            <DT>0.90.g:
                <DD>- sign extend ESI and EDI on the mouse callback
                <DD>- some minor package changes
            <DT>0.90.f:
                <DD>- first "official" release...
            </DL></DIR></DIR>
        </OL>

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="started">Getting started</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        D3X supports RAW/XMS/VCPI/DPMI platforms, but the optimal (read:
        safest and fastest) configuration is a plain DOS system with XMS.
        <OL>
        <HR>
        <LI>Raw images (Assembly):
        <HR>
            Any MZ-EXE can be extended provided it contains 32bit code, defines a stack
            and has no relocations. Also, to ease things, the pretty sophisticated MZ-EXE
            header is replaced with the very simple D3X1 header. But alas! I hear you cry.
            Worry not, the dirty job is done by <FONT COLOR=MAROON><B>StubX</B></FONT>, which is
            able to process both D3X1 and MZ-EXE; just type:
<PRE><FONT COLOR=MAROON><B>	&gt StubX -s my_MZapp.exe</B></FONT></PRE>
            or
<PRE><FONT COLOR=MAROON><B>	&gt StubX -s my_D3X1.exe</B></FONT></PRE>
            and voila! the dream comes true...<P>
            The D3X1 specifications:
            <OL TYPE=a>
            <LI>D3X1 header:
<PRE><FONT COLOR=TEAL><B>	d3x1_hdr	struc
        sign	dd	?	;signature 'D3X1'
        hdrsize	dd	?	;header size (bytes)
        binsize	dd	?	;binary size (bytes)
        admsize	dd	?	;additional memory (bytes)
        entry	dd	?	;entry point
        tos	dd	?	;top of stack
    d3x1_hdr	ends</B></FONT></PRE>
            <LI>Interface to D3X1:
<PRE><FONT COLOR=TEAL><B>	eflags		?202h
    cs,ds,ss	program block sel (cs = code32, ds=ss = data32)
    es		selector for transferbuffer (es:0 -&gt stubinfo)
    fs		flat data selector
    gs		flat code selector
    eip,esp		according to header
    .admsize	zeroed
    &lt;others&gt	undefined</B></FONT></PRE>
            <LI>Stubinfo area:
<PRE><FONT COLOR=TEAL><B>	[00h] (byte[])	=	'd3x1stub vM.mm'
    [10h] (dword)	=	size of stubinfo
    [14h] (dword)	=	&lt;unused&gt
    [18h] (dword)	=	memory block handle
    [1ch] (dword)	=	initial size (.binsize+.admsize)
    [20h] (word)	=	transferbuffer size
    [22h] (word)	=	transferbuffer data32 selector
    [24h] (word)	=	transferbuffer data segment
    [26h] (word)	=	PSP selector
    [28h] (word)	=	transferbuffer code16 selector
    [2ah] (word)	=	environment size
    [2ch] (dword)	=	platform (0=RAW, 1=XMS, 2=VCPI, 3=DPMI)</B></FONT></PRE>
            </OL>
        <HR>
        <LI>DJGPP images (v2 only):
        <HR>
            The simplest thing ever done:
<PRE><FONT COLOR=MAROON><B>	&gt StubX -s my_DJapp.exe</B></FONT></PRE>
        <HR>
        <LI>WATCOM images:
        <HR>
            Welcome to hell! Usually, the WATCOM images require an extended INT21h API.
            For most programs out there, the provided API and the DPMI host is more than
            sufficient. Also note that 16bit objects are loaded high, not low.<BR>
            The LE-EXE patching is a bit more complicated, but, again, have no fear;
            just run <FONT COLOR=MAROON><B>StubX</B></FONT> on such nasty monsters:
<PRE><FONT COLOR=MAROON><B>	&gt StubX -s my_LEapp.exe</B></FONT></PRE>
        </OL>

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="technical">Tech stuff</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        Although D3X does not support swapping, it has the capability to use paging
        even under XMS/RAW (through the VCPI allocation scheme); it is somehow slower
        and the pagetables might grow very high if physical RAM is high. On the other
        hand, it catches any illegal memory access through page faults. Introduced for
        future virtual memory support, this not-so-tested feature requires rebuilding.
        <OL>
        <HR>
        <LI>Interrupt engine:
        <HR>
            D3X doesn't relocate PIC at all. The algorithm it uses is:
            <UL>
            <LI>under DPMI: the DPMI host handles IRQs (D3X does nothing)
            <LI>under VCPI: D3X reads PIC from VCPI(DE0A) and uses it as is
            <LI>under RAW/XMS: D3X uses default IRQs, regardless of current
                mappings. For this, default IRQs must be called through real
                mode chaining (i.e. HBREAK 5.2 sets the first PIC to int50h,
                but int08h is still issued). This is necessary because some
                extenders when in XMS/RAW mode map 1st PIC to default (no
                matter where PIC actually is) without letting anyone know,
                and everything gets f#*%d up. The only thing that remains
                safe is default location of PIC.
            </UL>
            When issuing an interrupt, be sure you have a valid stack with at least
            64 bytes on it. The internal interrupt engine is based on the user
            stack (for speed) and if there's no stack space you have 100% chances
            to get a frozen reboot or a DoubleException.<BR>
            Some exception identification relies on that FLAGS can't resemble a valid
            code selector. If this happens, exceptions with error code would be treated as
            interrupts (which is wrong). Intel compatible CPUs won't allow this, because
            Bit1==1 in FLAGS and we run at ring 0. However, various specifications can use
            this bit, making it clearable. Thus, the simplest way to stay clear is to keep
            IOPL!=0 (bits 12-13 in FLAGS). Sane users shouldn't mess with this s#!t. That
            is, you can still f#*k the system, but don't come back to me crying. Also, if
            a TRAP/ABORT exception w/o error code occurs right after an instruction which
            ends with CD??, where ?? is the exception number, you'll get an interrupt:
<PRE>
        push	dword 3302h
        popfd
        mov	ax,01cdh
                &lt;- int01h, not debug exception</PRE>
            If an exception handler is installed, it will be called in a DPMI compliant
            manner: with the exception structure on the stack. You can alter *ONLY* those
            fields DPMI says you can, and nothing else. Anyway, there are two deviations
            from the rule:
            <UL>
            <LI>exception 0fh will be passed through the regular int chain; this is
                because of a nice feature of the interrupt controller being able to
                generate spurious IRQ7's. However, exception 0fh does not exist (by
                my knowledge).
            <LI>the client will be shut down if the exception is not raised from user
                task or if the DPMI locked stack is exhausted, possibly due to nested
                exceptions!
            </UL>
            When terminating due to unhandled exception, the returned DOS error code
            is: e0h + <FONT COLOR=RED>exception number</FONT>.
        <HR>
        <LI>DPMI host:
        <HR>
            <OL TYPE=a>
            <LI>DPMI functions:
                <TABLE BORDER=1 CELLSPACING=2>
                <TR><TH>Func.</TH><TH>Mode(s)</TH><TH>Ver</TH><TH>Description</TH></TR>
                <COLGROUP SPAN=3 ALIGN=CENTER>
                <TR><TD>0000h</TD><TD>P</TD><TD>0.9</TD><TD>Allocate LDT descriptors</TD></TR>
                <TR><TD>0001h</TD><TD>r</TD><TD>0.9+</TD><TD>Free LDT descriptor</TD></TR>
                <TR><TD>0003h</TD><TD>P</TD><TD>0.9</TD><TD>Get huge pointer increment</TD></TR>
                <TR><TD>0006h</TD><TD>P</TD><TD>0.9</TD><TD>Get segment base address</TD></TR>
                <TR><TD>0007h</TD><TD>P</TD><TD>0.9+</TD><TD>Set segment base address</TD></TR>
                <TR><TD>0008h</TD><TD>P</TD><TD>0.9+</TD><TD>Set segment limit</TD></TR>
                <TR><TD>0009h</TD><TD>P</TD><TD>0.9+</TD><TD>Set descriptor access rights</TD></TR>
                <TR><TD>000Ah</TD><TD>P</TD><TD>0.9</TD><TD>Create alias descriptor</TD></TR>
                <TR><TD>000Bh</TD><TD>P</TD><TD>0.9</TD><TD>Get descriptor</TD></TR>
                <TR><TD>000Ch</TD><TD>P</TD><TD>0.9+</TD><TD>Set descriptor</TD></TR>
                <TR><TD>0100h</TD><TD>r</TD><TD>0.9</TD><TD>Allocate DOS memory</TD></TR>
                <TR><TD>0101h</TD><TD>r</TD><TD>0.9+</TD><TD>Free DOS memory</TD></TR>
                <TR><TD>0102h</TD><TD>r</TD><TD>0.9</TD><TD>Resize DOS memory</TD></TR>
                <TR><TD>0200h</TD><TD>P</TD><TD>0.9</TD><TD>Get real-mode interrupt vector</TD></TR>
                <TR><TD>0201h</TD><TD>P</TD><TD>0.9</TD><TD>Set real-mode interrupt vector</TD></TR>
                <TR><TD>0202h</TD><TD>P</TD><TD>0.9</TD><TD>Get exception vector</TD></TR>
                <TR><TD>0203h</TD><TD>P</TD><TD>0.9</TD><TD>Set exception vector</TD></TR>
                <TR><TD>0204h</TD><TD>P</TD><TD>0.9</TD><TD>Get protected-mode int vector</TD></TR>
                <TR><TD>0205h</TD><TD>P</TD><TD>0.9</TD><TD>Set protected-mode int vector</TD></TR>
                <TR><TD>0300h</TD><TD>r</TD><TD>0.9</TD><TD>Simulate real-mode interrupt</TD></TR>
                <TR><TD>0301h</TD><TD>r</TD><TD>0.9</TD><TD>Call real-mode procedure (RETF)</TD></TR>
                <TR><TD>0302h</TD><TD>r</TD><TD>0.9</TD><TD>Call real-mode procedure (IRET)</TD></TR>
                <TR><TD>0303h</TD><TD>P</TD><TD>0.9</TD><TD>Allocate real mode call-back</TD></TR>
                <TR><TD>0304h</TD><TD>P</TD><TD>0.9</TD><TD>Free real mode call-back</TD></TR>
                <TR><TD>0400h</TD><TD>P</TD><TD>0.9</TD><TD>Get version</TD></TR>
                <TR><TD>0500h</TD><TD>P/r</TD><TD>0.9</TD><TD>Get free memory information</TD></TR>
                <TR><TD>0501h</TD><TD>P/r</TD><TD>0.9</TD><TD>Allocate memory block</TD></TR>
                <TR><TD>0502h</TD><TD>P/r</TD><TD>0.9</TD><TD>Free memory block</TD></TR>
                <TR><TD>0503h</TD><TD>P/r</TD><TD>0.9</TD><TD>Resize memory block</TD></TR>
                <TR><TD>0600h</TD><TD>P</TD><TD>bogus</TD><TD>Lock memory</TD></TR>
                <TR><TD>0601h</TD><TD>P</TD><TD>bogus</TD><TD>Unlock memory</TD></TR>
                <TR><TD>0604h</TD><TD>P</TD><TD>bogus</TD><TD>Get page size</TD></TR>
                <TR><TD>0800h</TD><TD>P</TD><TD>0.9</TD><TD>Map physical address</TD></TR>
                <TR><TD>0900h</TD><TD>P</TD><TD>0.9</TD><TD>Disable interrupts</TD></TR>
                <TR><TD>0901h</TD><TD>P</TD><TD>0.9</TD><TD>Enable interrupts</TD></TR>
                <TR><TD>0902h</TD><TD>P</TD><TD>0.9</TD><TD>Get interrupt state</TD></TR>
                </TABLE>
            <LI>Allocation strategy:
                <TABLE BORDER=0 CELLSPACING=3>
                <TR><TD>RAW</TD><TD>- kb granular</TD><TD>(best fit)</TD></TR>
                <TR><TD>XMS</TD><TD>- kb granular</TD><TD>(???)</TD></TR>
                <TR><TD>VCPI</TD><TD>- 4k granular </TD><TD>(first fit)</TD></TR>
                <TR><TD>DPMI </TD><TD>- ???</TD><TD>(???)</TD></TR>
                </TABLE>
            <LI>DPMI 0.90 deviation list:
                <UL>
                <LI>int24h is not handled at all
                <LI>D3X doesn't change stacks at IRQs for speed reasons.
                <LI>The selector modification functions don't allow non-present
                    selectors to prevent severe exceptions.
                <LI>The &lt;0.9+&gt functions act like &lt;1.0&gt;, but they never return an
                    error code.
                </UL>
            <LI>Tips & tricks:
                <UL>
                <LI>D3X checks for the presence of a DPMI host first. In that
                    case your program talks to the DPMI host and not D3X. As
                    discussed above, D3X doesn't support all DPMI 0.9 features,
                    so if you develop under a DPMI host be sure you sometimes
                    test with no DPMI!
                <LI>Some DPMI functions are *BOGUS* (i.e. locking functions),
                    because D3X doesn't have virtual memory and pages are
                    never swapped on disk. Though, these functions are useful
                    when running under another DPMI host (that uses virtual
                    memory), and therefore they return ok.
                <LI>In RAW mode, all extended memory is allocated (internally)
                    and if you run another app in shell mode, no extended memory
                    will be available. Sorry, may get fixed someday.
                </UL>
            </OL>
        <HR>
        <LI>INT21 extended API (WATCOM version only):
        <HR>
<PRE><FONT COLOR="#005000"><B>    1.DOS/09h - Write String to Standard Output:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 09h
    DS:EDX -> '$' terminated string to write

    Out: always successful
    ---------------------------------------------------------------------------

    2.DOS/1Ah - Set Disk Transfer Area:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 1Ah
    DS:EDX -> buffer for DTA

    Out: always successful
    ---------------------------------------------------------------------------

    3.DOS/1Bh - Get Allocation Information for Default Drive:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 1Bh

    Out: always successful:
        AL	= sectors per cluster
        ECX	= bytes per sector
        EDX	= total number of clusters
        DS:EBX -> media ID byte
    ---------------------------------------------------------------------------

    4.DOS/1Ch - Get Allocation Information for Specific Drive:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 1Ch
    DL	= drive number

    Out: if successful:
        same as DOS/1Bh
     if failed:
        AL	= FFh (invalid drive)
    ---------------------------------------------------------------------------

    5.DOS/1Fh - Get Drive Parameter Block for Default Drive:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 1Fh

    Out: if successful:
        DS:EBX -> drive parameter block
     if failed:
        AL	= FFh (invalid drive)
    ---------------------------------------------------------------------------

    6.DOS/25h - Set Interrupt Vector:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 25h
    AL	= interrupt number
    DS:EDX -> interrupt routine

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
    ---------------------------------------------------------------------------

    7.DOS/2Fh - Get Disk Transfer Area:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 2Fh

    Out: always successful:
        ES:EBX -> DTA
    ---------------------------------------------------------------------------

    8.DOS/32h - Get Drive Parameter Block for Specific Drive:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 32h
    DL	= drive number

    Out: if successful:
        AL	= 0
        DS:EBX -> drive parameter block
     if failed:
        AL	= FFh (invalid drive)
    ---------------------------------------------------------------------------

    9.DOS/34h - Get Address of InDOS Flag:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 34h

    Out: always successful:
        ES:EBX -> InDOS flag
    ---------------------------------------------------------------------------

    10.DOS/35h - Get Interrupt Vector:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 35h
    AL	= interrupt number

    Out: always successful:
        ES:EBX -> interrupt routine
    ---------------------------------------------------------------------------

    11.DOS/39h - Create Subdirectory:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 39h
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    12.DOS/3Ah - Remove Subdirectory:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 3Ah
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    13.DOS/3Bh - Set Directory:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 3Bh
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    14.DOS/3Ch - Create File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 3Ch
    CX	= attribute
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
        EAX	= handle
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    15.DOS/3Dh - Open File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 3Dh
    AL	= open code
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
        EAX	= handle
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    16.DOS/3Fh - Read From File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	 = 3Fh
    BX	 = file handle
    ECX	 = number of bytes to read
    DS:EDX -> buffer to read to

    Out: if successful:
        carry flag clear
        EAX	= number of bytes read
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    17.DOS/40h - Write To File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	 = 40h
    BX	 = file handle
    ECX	 = number of bytes to write
    DS:EDX -> buffer to write from

    Out: if successful:
        carry flag clear
        EAX	= number of bytes written
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    18.DOS/41h - Delete File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	 = 41h
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    19.DOS/43h - Get/Set File Attributes:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	 = 43h
    AL	 = function code
    CX	 = desired attributes
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
        CX	= current attributes
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    20.DOS/47h - Get Directory Path:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 47h
    DL	= drive number
    DS:ESI -> buffer for path

    Out: if successful:
        carry flag clear
        buffer pointed to by DS:ESI is filled with the path
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    21.DOS/48h - Allocate Memory Block:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 48h
    BX	= paragraphs to allocate

    Out: if successful:
        carry flag clear
        EAX	= selector for memory block
     if failed:
        carry flag set
        EAX	= error code
        EBX	= maximum paragraphs available
    ---------------------------------------------------------------------------

    22.DOS/49h - Free Memory Block:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 49h
    ES	= selector for memory block

    Out: if successful:
        carry flag clear
        ES	= NULL selector (to prevent loading invalid selector)
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    23.DOS/4Ah - Resize Memory Block:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 4Ah
    BX	= total paragraphs to allocate
    ES	= selector

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
        EBX	= maximum paragraphs available for specified block
    ---------------------------------------------------------------------------

    24.DOS/4Bh - Sub-Function 00h - Load and Execute Program:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 4Bh
    AL	= 00h
    DS:EDX -> path name
    ES:EBX -> parameter block

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    25.DOS/4Eh - Search for First Filename Match:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 4Eh
    CX	= file attribute
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
        EAX	= 0
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    26.DOS/4Fh - Search for Next Filename Match:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 4Fh

    Out: if successful:
        carry flag clear
        EAX	= 0
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    27.DOS/56h - Rename File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 56h
    DS:EDX -> old filename
    ES:EDI -> new filename

    Out: if successful:
        carry flag clear
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    28.DOS/5Bh - New File:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 5Bh
    CX	= attribute
    DS:EDX -> ASCIIZ path name

    Out: if successful:
        carry flag clear
        EAX	= handle
     if failed:
        carry flag set
        EAX	= error code
    ---------------------------------------------------------------------------

    29.DOS/62h - Get PSP:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AH	= 62h

    Out: always successful:
        EBX	PSP selector
    ---------------------------------------------------------------------------</B></FONT></PRE>
        <HR>
        <LI>INT33 extended API (WATCOM version only): carry flag is always set on error
        <HR>
<PRE><FONT COLOR="#005000"><B>    1.MOUSE/0009h - Set graphics pointer shape
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AX	= 0009h
    BX	= hot spot (horizontal)
    CX	= hot spot (vertical)
    DS:EDX -> pointer shape

    Out: none
    ---------------------------------------------------------------------------

    2.MOUSE/000Ch - Set event handler
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AX	= 000Ch
    CX	= event mask
    DS:EDX -> event handler code

    Out: none
    ---------------------------------------------------------------------------

    3.MOUSE/0016h - Save driver state
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AX	= 0016h
    DS:EDX -> buffer for driver state

    Out: none
    ---------------------------------------------------------------------------

    4.MOUSE/0017h - Load driver state
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    In:	AX	= 0017h
    DS:EDX -> buffer containing state

    Out: none
    ---------------------------------------------------------------------------</B></FONT></PRE>
        <HR>
        <LI>D3X errors:
        <HR>
            In some cases, the extender generates an error (`<FONT COLOR=RED><B>D3X: error 0x</B>??</FONT>'),
            and the program will exit with proper error code:
            <DL>
            <DT>D3X: error 0xff: need 386+ CPU
                <DD>You need 32bit PM. Buy a 386!
            <DT>D3X: error 0xfe: need DOS 3.0+
                <DD>This is needed for file I/O. Upgrade!
            <DT>D3X: error 0xfd: no DOS memory
                <DD>The extender could not initialize. Free up some low memory, use
                XMS/RAW (no pagetables), or decrease transferbuffer (min 2k).
            <DT>D3X: error 0xfc: DPMI host error
                <DD>An external DPMI host is present and unable to provide full
                services, or is 16bit. Remove the foreign host.
            <DT>D3X: error 0xfb: VCPI server error
                <DD>A VCPI server is present and unable to provide full services.
                Reboot without EMM (or update your Expanded Memory Manager).
            <DT>D3X: error 0xfa: V86 but no DPMI/VCPI
                <DD>Either the memory manager is in AUTO mode, or a strange virtual
                mode provider lies in the background. Stop it!
            <DT>D3X: error 0xf9: A20 gate failure
                <DD>The extender cannot take control over the A20 line. Either is a
                hardware error, or the memory manager is stupid.
            <DT>D3X: error 0xf8: unable to spawn image
                <DD>Cannot load the application file; it may be missing, corrupted or unsupported type.
            <DT>D3X: error 0xf7: no DPMI memory
                <DD>Failed allocating memory through (either internal or external) DPMI host.
            </DL>
        </OL>

    <HR SIZE=10 COLOR="#D8D8D8">
    <FONT SIZE=+1><B>
    <LI><A NAME="closing">Closing bytes, words, doublewords...</A>
    </B></FONT>
    <HR SIZE=10 COLOR="#D8D8D8">
        D3X is dedicated to all those who love the Art of Assembler.<P>
        The DOC files for D3X may be not complete, as I'm working on this alone and
        there are things I can't figure out for now... If you have something decent to
        comment/ask/suggest, do not hesitate to do so.<P>
        Creditz:
<PRE>	<B>Adam Seychell</B>     (DOS32 v0.1)		- idea and basics
    <B>CW Sandmann</B>       (CWSDPMI v0.90+ r4)	- task and int handling
    <B>Matthias Grimrath</B> (PMODE/DJ v1.2)	- VCPI setup
    <B>Michael Tippach</B>   (WDOSX v0.96 beta 1)	- LE loader</PRE>
        Greetz:
<PRE>	<B>Gerula</B> ~ AG (Gfx/Code/Muzak) - happy new games, if ever...</PRE>
    </OL>

    <BR>
    <HR SIZE=20 COLOR="#FFFFFF">
    <DIV ALIGN=RIGHT><FONT SIZE=4><B>...done by GrayWolf ~ Access Granted</B></FONT></DIV>
    <HR SIZE=20 COLOR="#FFFFFF">

</BODY>

</HTML>
